unit FileVersion;

interface

uses Windows, MiniSysUtils;

function GetFileVersion(const FileName: String; BlockCount: Word = 4): String;
function GetFileBuild(const FileName: String): Integer;

implementation

// this function reads the file ressource of "FileName" and returns
// the version number. "BlockCount" should be between 1-4 and means
// the precision of the version number, example:
//   BlockCount 3 -> "2.03.04"
function GetFileVersion(const FileName: String; BlockCount: Word = 4): String;
var
  iBufSize: DWORD;
  iRes: DWORD;
  pBuf: Pointer;
  pFileInfo: Pointer;
  iVer: Array[1..4] of Word;
begin
  // set default value
  Result := '';
  if (BlockCount < 1) or (BlockCount > 4) then
    BlockCount := 4;
  // does a version resource exist ?
  iBufSize := GetFileVersionInfoSize(PChar(FileName), iRes);
  if (iBufSize > 0) then
  begin
    GetMem(pBuf, iBufSize);
    try
    // get information
    GetFileVersionInfo(PChar(FileName), 0, iBufSize, pBuf);
    VerQueryValue(pBuf, '\', pFileInfo, iRes);
    // read version blocks
    iRes := PVSFixedFileInfo(pFileInfo)^.dwFileVersionMS;
    iVer[1] := HiWord(iRes);
    iVer[2] := LoWord(iRes);
    iRes := PVSFixedFileInfo(pFileInfo)^.dwFileVersionLS;
    iVer[3] := HiWord(iRes);
    iVer[4] := LoWord(iRes);
    finally
      FreeMem(pBuf);
    end;
    // format result string
    for iRes := 1 to BlockCount do
    begin
      if iRes = 1 then
        Result := IntToStr(iVer[iRes])
      else
        Result := Result + '.' + Format('%.1d', [iVer[iRes]]);
    end;
  end;
end;

// this function reads the file ressource of "FileName" and returns
// the version build number. (modified getfileversion)
function GetFileBuild(const FileName: String): Integer;
var
  iBufSize: DWORD;
  iRes: DWORD;
  pBuf: Pointer;
  pFileInfo: Pointer;
  iVer: Array[1..4] of Word;
begin
  // set default value
  Result := 0;
  // does a version resource exist ?
  iBufSize := GetFileVersionInfoSize(PChar(FileName), iRes);
  if (iBufSize > 0) then
  begin
    GetMem(pBuf, iBufSize);
    try
    // get information
    GetFileVersionInfo(PChar(FileName), 0, iBufSize, pBuf);
    VerQueryValue(pBuf, '\', pFileInfo, iRes);
    // read version blocks
    iRes := PVSFixedFileInfo(pFileInfo)^.dwFileVersionMS;
    iVer[1] := HiWord(iRes);
    iVer[2] := LoWord(iRes);
    iRes := PVSFixedFileInfo(pFileInfo)^.dwFileVersionLS;
    iVer[3] := HiWord(iRes);
    iVer[4] := LoWord(iRes);
    finally
      FreeMem(pBuf);
    end;
    // give build number
    Result := iVer[4];
  end;
end;

end.